package cn.com.twoke.app.pin_dou_dou.utils;

import cn.com.twoke.app.pin_dou_dou.core.Settings;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.colors.Color;
import com.itextpdf.kernel.colors.DeviceRgb;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.*;
import com.itextpdf.layout.properties.HorizontalAlignment;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.UnitValue;
import com.itextpdf.layout.properties.VerticalAlignment;
import lombok.extern.slf4j.Slf4j;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * PDF说明书生成工具类
 */
@Slf4j
public class PdfInstructionUtils {

    // PDF页面尺寸
    private static final PageSize PAGE_SIZE = PageSize.A4;
    // 默认字体大小
    private static final float TITLE_FONT_SIZE = 20f;
    private static final float SECTION_FONT_SIZE = 16f;
    private static final float TEXT_FONT_SIZE = 12f;
    // 默认边距
    private static final float MARGIN = 50f;

    /**
     * 生成拼豆图说明书PDF
     * @param outputFile 输出PDF文件路径
     * @param originalImage 无分区的完整拼豆图
     * @param partitionedImage 带分区线的完整拼豆图
     * @param partitionImages 分区图像列表
     * @param partitionNames 分区名称列表
     * @param partitionColorStats 分区颜色统计信息
     * @throws IOException IO异常
     */
    public static void generateInstructionPdf(String outputFile,
                                              BufferedImage originalImage,
                                              BufferedImage partitionedImage,
                                              List<BufferedImage> partitionImages,
                                              List<String> partitionNames,
                                              List<Map<String, Object>> partitionColorStats) throws IOException {
        // 创建PDF文档
        PdfWriter writer = new PdfWriter(outputFile);
        PdfDocument pdf = new PdfDocument(writer);
        Document document = new Document(pdf, PAGE_SIZE);
        document.setMargins(MARGIN, MARGIN, MARGIN, MARGIN);

        try {
            // 添加封面
            addCoverPage(document);

            // 添加无分区的完整拼豆图
            addFullImageSection(document, "完整拼豆图（无分区）", originalImage);

            // 添加带分区线的完整拼豆图
            addFullImageSection(document, "完整拼豆图（带分区）", partitionedImage);

            // 添加各分区详细信息
            addPartitionDetails(document, partitionImages, partitionNames, partitionColorStats);

            // 关闭文档
            document.close();
            log.info("PDF说明书生成完成：{}", outputFile);
        } catch (Exception e) {
            log.error("生成PDF说明书时发生错误", e);
            throw e;
        }
    }
   static PdfFont sysFont;

    static {
        try {
            sysFont = PdfFontFactory.createFont("C:/Windows/Fonts/simhei.ttf",
                    PdfEncodings.IDENTITY_H, // 支持中文编码
                    PdfFontFactory.EmbeddingStrategy.FORCE_EMBEDDED);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 添加封面页
     * @param document PDF文档
     * @throws IOException IO异常
     */
    private static void addCoverPage(Document document) throws IOException {
        // 标题
        Paragraph title = new Paragraph("拼豆图说明书")
                .setFont(sysFont)
                .setTextAlignment(TextAlignment.CENTER)
                .setFontSize(TITLE_FONT_SIZE)
                .setBold()
                .setFontColor(new DeviceRgb(0, 102, 204)); // 蓝色字体

        document.add(title);

        // 空行
        document.add(new Paragraph("\n"));

        // 说明文字
        Paragraph description = new Paragraph("本说明书包含拼豆图的完整设计和分区详细信息，" +
                "请按照说明进行拼豆制作。")
                .setFont( sysFont)
                .setTextAlignment(TextAlignment.CENTER)
                .setFontSize(TEXT_FONT_SIZE);
        document.add(description);

        // 添加分页
        document.add(new AreaBreak());
    }

    /**
     * 添加完整图像部分
     * @param document PDF文档
     * @param title 标题
     * @param image 图像
     * @throws IOException IO异常
     */
    private static void addFullImageSection(Document document, String title, BufferedImage image) throws IOException {
        // 添加标题
        Paragraph sectionTitle = new Paragraph(title)
                .setFont(sysFont)
                .setFontSize(SECTION_FONT_SIZE)
                .setBold()
                .setFontColor(new DeviceRgb(0, 102, 204)) // 蓝色字体
                .setTextAlignment(TextAlignment.CENTER)
                .setMarginBottom(20f)
                .setBackgroundColor(new DeviceRgb(230, 240, 255)) // 浅蓝色背景
                .setPadding(10f);
        document.add(sectionTitle);

        // 添加图像
        Image pdfImage = convertBufferedImageToPdfImage(image);
        // 调整图像大小以适应页面
        float pageWidth = PAGE_SIZE.getWidth() - 2 * MARGIN;
        float pageHeight = PAGE_SIZE.getHeight() - 2 * MARGIN;
        float imageWidth = pdfImage.getImageWidth();
        float imageHeight = pdfImage.getImageHeight();
        
        // 计算缩放比例
        float scale = Math.min(pageWidth / imageWidth, pageHeight / imageHeight);
        if (scale < 1.0f) {
            pdfImage.setWidth(imageWidth * scale);
            pdfImage.setHeight(imageHeight * scale);
        }
        
        // 居中显示
        pdfImage.setTextAlignment(TextAlignment.CENTER);
        document.add(pdfImage);

        // 添加分页
        document.add(new AreaBreak());
    }

    /**
     * 添加分区详细信息
     * @param document PDF文档
     * @param partitionImages 分区图像列表
     * @param partitionNames 分区名称列表
     * @param partitionColorStats 分区颜色统计信息
     * @throws IOException IO异常
     */
    private static void addPartitionDetails(Document document,
                                            List<BufferedImage> partitionImages,
                                            List<String> partitionNames,
                                            List<Map<String, Object>> partitionColorStats) throws IOException {
        for (int i = 0; i < partitionImages.size(); i++) {
            // 添加分区标题
            String partitionName = partitionNames.get(i);
            Paragraph sectionTitle = new Paragraph("分区 " + partitionName + " 详细信息")
                    .setFont( sysFont)
                    .setFontSize(SECTION_FONT_SIZE)
                    .setBold()
                    .setFontColor(new DeviceRgb(0, 102, 204)) // 蓝色字体
                    .setTextAlignment(TextAlignment.CENTER)
                    .setMarginBottom(20f)
                    .setBackgroundColor(new DeviceRgb(230, 240, 255)) // 浅蓝色背景
                    .setPadding(10f);
            document.add(sectionTitle);

            // 添加分区图像
            BufferedImage partitionImage = partitionImages.get(i);
            Image pdfImage = convertBufferedImageToPdfImage(partitionImage);
            
            // 调整图像大小以适应页面
            float pageWidth = PAGE_SIZE.getWidth() - 2 * MARGIN;
            float pageHeight = PAGE_SIZE.getHeight() - 2 * MARGIN;
            float imageWidth = pdfImage.getImageWidth();
            float imageHeight = pdfImage.getImageHeight();
            
            // 计算缩放比例
            float scale = Math.min(pageWidth / imageWidth, (pageHeight - 100) / imageHeight);
            if (scale < 1.0f) {
                pdfImage.setWidth(imageWidth * scale);
                pdfImage.setHeight(imageHeight * scale);
            }
            
            // 居中显示
            pdfImage.setTextAlignment(TextAlignment.CENTER);
            pdfImage .setMarginBottom(20f);
            document.add(pdfImage);

            // 添加颜色统计表格
            addColorStatsTable(document, partitionColorStats.get(i));

            // 添加分页（除了最后一个分区）
            if (i < partitionImages.size() - 1) {
                document.add(new AreaBreak());
            }
        }
    }

    /**
     * 添加颜色统计表格
     * @param document PDF文档
     * @param colorStats 颜色统计信息
     */
    private static void addColorStatsTable(Document document, Map<String, Object> colorStats) {
        try {
            // 创建表格（4列：序号、颜色编码、色块、颗粒数）
            Table table = new Table(UnitValue.createPercentArray(new float[]{1, 3, 2, 2}))
                    .setWidth(UnitValue.createPercentValue(100))
                    .setMarginBottom(20f);

            // 设置表头样式
            Cell header1 = new Cell().add(new Paragraph("序号")).setFont( sysFont).setBold().setTextAlignment(TextAlignment.CENTER);
            Cell header2 = new Cell().add(new Paragraph("颜色编码(" + Settings.getColorScheme() + ")")).setFont( sysFont).setBold().setTextAlignment(TextAlignment.CENTER);
            Cell header3 = new Cell().add(new Paragraph("色块")).setBold().setFont( sysFont).setTextAlignment(TextAlignment.CENTER);
            Cell header4 = new Cell().add(new Paragraph("颗粒数")).setBold().setFont( sysFont) .setTextAlignment(TextAlignment.CENTER);
            
            table.addHeaderCell(header1);
            table.addHeaderCell(header2);
            table.addHeaderCell(header3);
            table.addHeaderCell(header4);

            // 按名称排序颜色统计信息
            Map<String, Object> sortedColorStats = new TreeMap<>();
            for (Map.Entry<String, Object> entry : colorStats.entrySet()) {
                sortedColorStats.put(entry.getKey(), entry.getValue());
            }

            // 添加数据行
            int index = 1;
            for (Map.Entry<String, Object> entry : sortedColorStats.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                
                // 解析颜色键和标识字符
                String[] parts = key.split("_");
                String colorKey = parts[0];
                String mark = parts[1];
                
                // 创建序号单元格
                Cell indexCell = new Cell().add(new Paragraph(String.valueOf(index)))
                        .setVerticalAlignment(VerticalAlignment.MIDDLE)
                        .setTextAlignment(TextAlignment.CENTER);
                
                // 创建颜色编码单元格
                Cell codeCell = new Cell().add(new Paragraph(mark))
                        .setVerticalAlignment(VerticalAlignment.MIDDLE).setTextAlignment(TextAlignment.CENTER);
                
                // 创建色块单元格（32x32的色块）
                Cell colorCell = new Cell();
                // 创建一个32x32的小方块来展示颜色
                Div colorDiv = new Div()
                        .setWidth(UnitValue.createPointValue(32))
                        .setHeight(UnitValue.createPointValue(32))
                        .setBackgroundColor(parseColorFromString(colorKey))
                        .setTextAlignment(TextAlignment.CENTER)
                        .setHorizontalAlignment(HorizontalAlignment.CENTER)
                        ;
                colorCell.add(colorDiv)
                        .setTextAlignment(TextAlignment.CENTER)
                        .setHorizontalAlignment(HorizontalAlignment.CENTER)
                ;
                
                // 创建颗粒数单元格
                Cell countCell = new Cell().add(new Paragraph(value.toString()))
                        .setVerticalAlignment(VerticalAlignment.MIDDLE)
                        .setTextAlignment(TextAlignment.CENTER);
                
                // 添加单元格到表格
                table.addCell(indexCell);
                table.addCell(codeCell);
                table.addCell(colorCell);
                table.addCell(countCell);
                
                index++;
            }

            document.add(table);
        } catch (Exception e) {
            log.error("添加颜色统计表格时发生错误", e);
        }
    }

    /**
     * 将BufferedImage转换为PDF Image
     * @param bufferedImage BufferedImage对象
     * @return PDF Image对象
     * @throws IOException IO异常
     */
    private static Image convertBufferedImageToPdfImage(BufferedImage bufferedImage) throws IOException {
        // 将BufferedImage转换为字节数组
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "png", baos);
        byte[] imageBytes = baos.toByteArray();
        baos.close();

        // 创建PDF Image
        ImageData imageData = ImageDataFactory.create(imageBytes);
        return new Image(imageData);
    }

    /**
     * 将Java Color转换为iText Color
     * @param color Java Color对象
     * @return iText Color对象
     */
    private static Color convertJavaColorToPdfColor(java.awt.Color color) {
        return new DeviceRgb(color.getRed(), color.getGreen(), color.getBlue());
    }
    
    /**
     * 从颜色字符串解析颜色
     * @param colorString 颜色字符串（格式：#RRGGBB）
     * @return iText Color对象
     */
    private static Color parseColorFromString(String colorString) {
        try {
            // 移除#前缀
            String hexColor = colorString.replace("#", "");
            
            // 解析RGB值
            int red = Integer.parseInt(hexColor.substring(0, 2), 16);
            int green = Integer.parseInt(hexColor.substring(2, 4), 16);
            int blue = Integer.parseInt(hexColor.substring(4, 6), 16);
            
            return new DeviceRgb(red, green, blue);
        } catch (Exception e) {
            // 如果解析失败，返回黑色
            return new DeviceRgb(0, 0, 0);
        }
    }
}